Skip to content

TLS Milestone 1: host OpenSSL transport + opt-in plumbing - #15

Merged
sidick merged 2 commits into
mainfrom
tls/milestone-1-host-openssl
Aug 29, 2026
Merged

TLS Milestone 1: host OpenSSL transport + opt-in plumbing#15
sidick merged 2 commits into
mainfrom
tls/milestone-1-host-openssl

Conversation

@sidick

@sidick sidick commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Milestone 1 of the TLS plan for #3 (plan posted as a comment there): prove the transport-vtable seam and opt-in flag threading entirely on the host, before any AmiSSL/Amiga-side work.

What this delivers

  • src/host/transport_openssl.c/.h — a new mqtt_transport over host OpenSSL (1.1+/3.x), structurally mirroring transport_bsd.c. Certificate and hostname verification on by default (system trust store via SSL_CTX_set_default_verify_paths(), SNI + SSL_set1_host); explicit insecure-skip-verify mode; same 1s SO_RCVTIMEO poll trick as the plaintext transport; WANT_READ/WANT_WRITE (and the SO_RCVTIMEO EAGAIN tick) map to the vtable's "0 = would-block, not an error" contract; SSL_get_verify_result() is read before SSL_free() on handshake failure; no leaks on any error path; no global state. Zero changes to src/core.
  • Opt-in flags — TLS is opt-in and off by default everywhere (hard project requirement). Host getopt gains -s (TLS, verify on) / -S (TLS, skip verify); the Amiga ReadArgs templates gain TLS/S/TLSINSECURE/S (plumbed into tool_opts only — nothing consumes them on the Amiga side until Milestone 3's AmiSSL wiring).
  • TLS-aware default port — both parsers now leave the port as a 0 sentinel and resolve it after parsing: 8883 with TLS, otherwise exactly 1883. Plaintext behaviour with no flags is byte-for-byte unchanged.
  • tests/broker/tls-smoke.sh / make broker-tls-smoke — mirrors smoke.sh: scratch Mosquitto with a TLS listener and an on-the-fly self-signed cert. Proves (1) verify-on round-trip with the cert as trust anchor via SSL_CERT_FILE, (2) skip-verify round-trip against the untrusted cert, (3) verify-on with no trust anchor is rejected. New CI job on the existing broker path filter; the two container jobs' apt-get lines gain libssl-dev pkg-config since make cli now links OpenSSL.
  • Docsuserdocs/CLI-Reference.md gains a "Host development builds" section for -s/-S, noting TLS is opt-in and host-only for now.

Verification (all run locally)

  • make test-host: 249 passed, 0 failed; make cli and make m68k build warning-free; make lint clean
  • make broker-smoke and make broker-tls-smoke: all checks pass
  • No -s → still connects plaintext on port 1883 by default (checked against a real broker on 1883)

Deliberately left for later milestones

  • Milestone 2: AmiSSL transport, MIDGE_TLS build flag, SDK fetch, on-target TLS smoke (needs the hardware-timing spike first)
  • Milestone 3: wiring opts.tls through the Amiga CLIs and mqtt.library (mco_UseTLS, MQTTERR_NOTLS), full Amiga flag docs
  • Deferred by plan: CA-file override flag, cipher/protocol tuning

🤖 Generated with Claude Code

https://claude.ai/code/session_01QWq1CRLCQy9AaD9UtLRSM9

New src/host/transport_openssl.c/.h implements mqtt_transport over host
OpenSSL: verification on by default (system trust store, SNI + hostname
check), -S/insecure opt-out, SO_RCVTIMEO poll ticks and WANT_READ/
WANT_WRITE mapped to the vtable's would-block contract, and
SSL_get_verify_result() read before SSL_free() on handshake failure.

TLS is strictly opt-in (never default-on): new -s/-S getopt flags and
TLS/S,TLSINSECURE/S ReadArgs switches populate tool_opts.tls/
tls_insecure; both parsers now resolve the default port after parsing
(8883 with TLS, otherwise exactly 1883 as before). The Amiga side only
plumbs the flags for now - the AmiSSL transport lands in Milestone 2/3.

tests/broker/tls-smoke.sh (make broker-tls-smoke, plus a CI job on the
existing broker filter) proves verify-on against a provisioned CA,
skip-verify against an untrusted cert, and that verify-on rejects an
untrusted cert. userdocs/CLI-Reference.md documents the host flags.

Part of #3.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWq1CRLCQy9AaD9UtLRSM9
@sidick
sidick force-pushed the tls/milestone-1-host-openssl branch from 400cda6 to df0a45e Compare August 29, 2026 20:18
ci / test-host and ci / build run make test-host/make build inside the
shared amiga-dev CI image via a reusable workflow this repo can't add
an apt-get step to, and that image has no OpenSSL headers - so linking
-lssl -lcrypto unconditionally into mqtt_pub-host/mqtt_sub-host broke
CI. Probe for openssl/ssl.h at Makefile-configure time instead: when
present, build transport_openssl.c in as before; when absent, the host
tools still build cleanly and reject -s/-S at runtime with a clear
"not supported in this build" message rather than failing to link.
broker-tls-smoke's own job (a stock ubuntu-latest runner, not the
amiga-dev container) still gets full TLS support either way. Same
idiom the TLS plan already designs for Milestone 2's AmiSSL SDK,
pulled forward to the host build; mirrors amiauth's own precedent of
keeping an optional host OpenSSL dependency out of its core build/test
verbs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWq1CRLCQy9AaD9UtLRSM9
@sidick
sidick enabled auto-merge (squash) August 29, 2026 20:30
@sidick
sidick merged commit 19119fc into main Aug 29, 2026
11 checks passed
@sidick
sidick deleted the tls/milestone-1-host-openssl branch August 29, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant